package com.fling.screen;

import java.util.ArrayList;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.audio.Music;
import com.badlogic.gdx.files.FileHandle;
import com.badlogic.gdx.graphics.Camera;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.Texture.TextureWrap;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.TextureAtlas;
import com.badlogic.gdx.graphics.g2d.freetype.FreeTypeFontGenerator;
import com.badlogic.gdx.graphics.g2d.freetype.FreeTypeFontGenerator.FreeTypeFontParameter;
import com.badlogic.gdx.scenes.scene2d.InputEvent;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.scenes.scene2d.ui.Image;
import com.badlogic.gdx.scenes.scene2d.ui.ImageButton;
import com.badlogic.gdx.scenes.scene2d.ui.Label;
import com.badlogic.gdx.scenes.scene2d.ui.Label.LabelStyle;
import com.badlogic.gdx.scenes.scene2d.ui.Skin;
import com.badlogic.gdx.scenes.scene2d.ui.Table;
import com.badlogic.gdx.scenes.scene2d.ui.TextButton;
import com.badlogic.gdx.scenes.scene2d.ui.TextButton.TextButtonStyle;
import com.badlogic.gdx.scenes.scene2d.utils.ClickListener;
import com.fling.Constants;
import com.fling.FlingHero;
import com.fling.Locator;
import com.fling.background.BackgroundBlockManager;
import com.fling.observer.Event;
import com.fling.services.GameServiceInterface;

public class MenuScreen implements Screen, Constants {
	private BitmapFont white, whiteLarge;
	private Stage stage;
	private Table table;
	private TextButton buttonExit, buttonPlay, buttonPlay2;
	private ImageButton buttonLeaderboard, buttonAchv, buttonSignIn, buttonSignOut;
	private Label heading;
	private Skin skin;
	private TextureAtlas atlas;
	private TextButtonStyle textButtonStyle, playStyle, exitStyle;
	private final ArrayList<TransitionEffect> effects;
	private Texture background;
	private SpriteBatch uiBatch;
	private FlingHero game;
	private BackgroundBlockManager backgroundManager;
	private Camera camera;
	private SpriteBatch gameSprites;
	private Music music;
	private ImageButton mute, unmute;
	private float musicTimer;
	public static int COUNT = 1;

	public MenuScreen(final FlingHero game, Camera camera, final GameServiceInterface leaderboard) {
		this.game = game;
		musicTimer = 0;
		music =Gdx.audio.newMusic(Gdx.files.internal("data/sound/menu_music.mp3"));

		this.camera = camera;
		stage = new Stage();
		uiBatch = new SpriteBatch();
		gameSprites = new SpriteBatch();

		background = new Texture(BACKGROUNDMAIN);
		background.setWrap(TextureWrap.Repeat, TextureWrap.Repeat);

		FileHandle fontFile = Gdx.files.internal(FONT);
		FreeTypeFontGenerator generator = new FreeTypeFontGenerator(fontFile);
		FreeTypeFontParameter param = new FreeTypeFontParameter();
		param.size = (int) (80 / UI_SCALE);
		white = generator.generateFont(param);
		param.size = (int) (100 / UI_SCALE);
		whiteLarge = generator.generateFont(param);
		generator.dispose();

		atlas = new TextureAtlas(Gdx.files.internal("data/button.pack"));
		skin = new Skin(atlas);
		table = new Table(skin);
		table.setBounds(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());

		textButtonStyle = new TextButtonStyle();
		textButtonStyle.up = skin.getDrawable("button.up");
		textButtonStyle.down = skin.getDrawable("button.down");
		textButtonStyle.pressedOffsetX = 1;
		textButtonStyle.pressedOffsetY = -1;
		textButtonStyle.font = white;
		playStyle = new TextButtonStyle(textButtonStyle);
		playStyle.fontColor = new Color(0.5f, 0.5f, 1.0f, 1);
		exitStyle = new TextButtonStyle(textButtonStyle);
		exitStyle.fontColor = Color.WHITE;

		// create a transition screen
		effects = new ArrayList<TransitionEffect>();
		effects.add(new FadeOutTransitionEffect(0.5f));
		effects.add(new FadeInTransitionEffect(0.5f));

		// create buttons
		buttonSignIn = new ImageButton(new Image(new Texture(Gdx.files.internal(SIGN_IN))).getDrawable());
		buttonSignIn.setScale(1f / UI_SCALE);
		buttonSignIn.getImage().setScale(1f / UI_SCALE);
		buttonSignIn.addListener(new ClickListener() {
			@Override
			public void clicked(InputEvent event, float x, float y) {
				Locator.getDevice().googleLogIn();
			}

		});
		
		buttonSignOut = new ImageButton(new Image(new Texture(Gdx.files.internal(SIGN_OUT))).getDrawable());
		buttonSignOut.setScale(1f / UI_SCALE);
		buttonSignOut.getImage().setScale(1f / UI_SCALE);
		buttonSignOut.addListener(new ClickListener() {
			@Override
			public void clicked(InputEvent event, float x, float y) {
				Locator.getDevice().googleLogOff();
			}

		});

		buttonAchv = new ImageButton(new Image(new Texture(Gdx.files.internal(ACHIEVEMENT))).getDrawable());
		buttonAchv.setScale(0.8f / UI_SCALE);
		buttonAchv.getImage().setScale(0.8f / UI_SCALE);
		buttonAchv.addListener(new ClickListener() {
			@Override
			public void clicked(InputEvent event, float x, float y) {
				Locator.getDevice().showAchievements();
			}

		});

		buttonLeaderboard = new ImageButton(new Image(new Texture(Gdx.files.internal(LEADERBOARD))).getDrawable());
		buttonLeaderboard.setScale(0.8f / UI_SCALE);
		buttonLeaderboard.getImage().setScale(0.8f / UI_SCALE);
		buttonLeaderboard.addListener(new ClickListener() {
			@Override
			public void clicked(InputEvent event, float x, float y) {
				Locator.getDevice().showLeaderboardScore();
			}

		});

		buttonPlay = new TextButton("Easy", exitStyle);
		buttonPlay.addListener(new ClickListener() {
			@Override
			public void clicked(InputEvent event, float x, float y) {
				game.getGameScreen().getSubject().notify(null, Event.EVENT_CLICK);
				Locator.setDifficutly(Locator.EASY);
				startGame();
			}
		});
		buttonPlay.pad(10.0f);

		buttonPlay2 = new TextButton("Hard", exitStyle);
		buttonPlay2.addListener(new ClickListener() {
			@Override
			public void clicked(InputEvent event, float x, float y) {
				game.getGameScreen().getSubject().notify(null, Event.EVENT_CLICK);
				game.getGameScreen().getSubject().notify(null, Event.EVENT_HARD_MODE);
				Locator.setDifficutly(Locator.HARD);
				startGame();
			}
		});
		buttonPlay2.pad(10.0f);

		buttonExit = new TextButton("Exit", exitStyle);
		buttonExit.addListener(new ClickListener() {
			@Override
			public void clicked(InputEvent event, float x, float y) {
				game.getGameScreen().getSubject().notify(null, Event.EVENT_CLICK);
				Locator.writeSave();
				Gdx.app.exit();
			}
		});
		buttonExit.pad(10.0f);

		Image i = new Image(new Texture(Gdx.files.internal(MUTE)));
		mute = new ImageButton(i.getDrawable());
		mute.addListener(new ClickListener() {
			@Override
			public void clicked(InputEvent event, float x, float y) {
				Locator.setMute(false);
				music.setVolume(DEFAULT_VOLUME);
				game.getGameScreen().getSubject().notify(null, Event.EVENT_CLICK);
				addMute();
			}
		});
		mute.setPosition(Gdx.graphics.getWidth() * 0.85f, Gdx.graphics.getHeight() * 0.925f);
		mute.setScale(2 / UI_SCALE_X, 2 / UI_SCALE_Y);
		mute.getImage().setScale(2 / UI_SCALE_X, 2 / UI_SCALE_Y);

		i = new Image(new Texture(Gdx.files.internal(UNMUTE)));
		unmute = new ImageButton(i.getDrawable());
		unmute.addListener(new ClickListener() {
			@Override
			public void clicked(InputEvent event, float x, float y) {
				Locator.setMute(true);
				music.setVolume(0);
				addMute();
			}
		});
		unmute.setPosition(Gdx.graphics.getWidth() * 0.85f, Gdx.graphics.getHeight() * 0.92f);
		unmute.setScale(2 / UI_SCALE_X, 2 / UI_SCALE_Y);
		unmute.getImage().setScale(2 / UI_SCALE_X, 2 / UI_SCALE_Y);

		// create title
		LabelStyle headingStyle = new LabelStyle(whiteLarge, Color.WHITE);
		heading = new Label("Fling Hero", headingStyle);
		heading.setPosition(Gdx.graphics.getWidth() * 0.1f, Gdx.graphics.getHeight() * 0.8f);

		buttonPlay.setPosition(Gdx.graphics.getWidth() * 0.1f, Gdx.graphics.getHeight() * 0.6f);
		buttonPlay2.setPosition(Gdx.graphics.getWidth() * 0.1f, Gdx.graphics.getHeight() * 0.48f);
		buttonExit.setPosition(Gdx.graphics.getWidth() * 0.1f, Gdx.graphics.getHeight() * 0.36f);

		buttonSignIn.setPosition(Gdx.graphics.getWidth() * 0.1f, Gdx.graphics.getHeight() * 0.18f);
		buttonSignOut.setPosition(Gdx.graphics.getWidth() * 0.1f, Gdx.graphics.getHeight() * 0.18f);
		buttonLeaderboard.setPosition(Gdx.graphics.getWidth() * 0.42f, Gdx.graphics.getHeight() * 0.18f);
		buttonAchv.setPosition(Gdx.graphics.getWidth() * 0.7f, Gdx.graphics.getHeight() * 0.18f);
		stage.addActor(buttonPlay);
		stage.addActor(buttonPlay2);
		stage.addActor(buttonSignIn);
		stage.addActor(buttonSignOut);
		stage.addActor(buttonExit);
		stage.addActor(heading);
		stage.addActor(mute);
		stage.addActor(unmute);
		stage.addActor(buttonLeaderboard);
		stage.addActor(buttonAchv);
		addMute();

		backgroundManager = new BackgroundBlockManager(false);
		if (!Locator.getServices().isUpdated()) {
			switchText(Locator.getServices().isSignedIn());
		}

	}

	public void switchText(boolean didSignIn) {
		if (didSignIn) {
			buttonSignOut.setVisible(true);
			buttonSignOut.setDisabled(false);
			buttonSignIn.setDisabled(true);
			buttonSignIn.setVisible(false);
		} else {
			buttonSignIn.setVisible(true);
			buttonSignIn.setDisabled(false);
			buttonSignOut.setDisabled(true);
			buttonSignOut.setVisible(false);
		}
	}

	public void addMute() {
		if (Locator.isMute()) {
			mute.setVisible(true);
			mute.setDisabled(false);
			unmute.setDisabled(true);
			unmute.setVisible(false);
		} else {
			mute.setDisabled(true);
			mute.setVisible(false);
			unmute.setDisabled(false);
			unmute.setVisible(true);
		}
		Locator.writeSave();
	}

	protected void startGame() {
		final GameScreen next = game.getGameScreen();
		game.getGameScreen().init();
		next.show();
		Screen transitionScreen = new TransitionScreen(game, this, next, effects);
		game.setScreen(transitionScreen);
	}

	@Override
	public void render(float delta) {
		Gdx.gl.glClearColor(0.5098f, 0.4706f, 0.8392f, 1);
		Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
		uiBatch.begin();
		uiBatch.draw(background, 0, 0, background.getWidth() * COUNT, background.getHeight() * COUNT, 0, COUNT, COUNT, 0);
		uiBatch.end();

		gameSprites.setProjectionMatrix(camera.combined);
		gameSprites.begin();
		backgroundManager.render(gameSprites);
		gameSprites.end();

		backgroundManager.update(delta);
		stage.act(delta);
		stage.draw();

		if (!music.isPlaying() && !Locator.isMute()) {
			musicTimer += delta;
			if (musicTimer > 2) {
				musicTimer = 0;
				music.play();
			}
		}
	}

	@Override
	public void resize(int width, int height) {
		stage.getViewport().update(width, height, true);
		table.invalidateHierarchy();
		table.setSize(width, height);
	}

	@Override
	public void show() {
		effects.clear();
		effects.add(new FadeOutTransitionEffect(0.5f));
		effects.add(new FadeInTransitionEffect(0.5f));
		Gdx.input.setInputProcessor(stage);
	}

	@Override
	public void hide() {
		Gdx.input.setInputProcessor(null);
		music.pause();
	}

	@Override
	public void pause() {
	}

	@Override
	public void resume() {
	}

	@Override
	public void dispose() {
		stage.dispose();
		atlas.dispose();
		skin.dispose();
		white.dispose();
	}

}